// 1.插件
// 2.两个组件

// import Link from './krouter-link';
import View from './krouter-view';

// vue插件：
// function
// 要求必须有一个install，将来会被Vue.use调用
let Vue; // 保存Vue构造函数，插件中要使用，不导入还能用
class VueRouter {
    constructor(options) {
        this.$options = options;

        // 把current作为响应式数据
        // 将来发生变化，router-view的render函数能够再次执行
        // const initial = window.location.hash.slice(1) || "/";
        // Vue.util.defineReactive(this, 'current', initial)
        this.current = window.location.hash.slice(1) || '/';
        Vue.util.defineReactive(this, 'matched', []);

        // matched方法可以递归遍历路由表，获得匹配关系数组
        this.match();
        // 监听hash变化
        window.addEventListener("hashchange", this.onHashChange.bind(this));
        window.addEventListener("load", this.onHashChange.bind(this));
    }

    onHashChange() {
        this.current = window.location.hash.slice(1);
        this.matched = [];
        this.match();
    }
    match(routes) {
        routes = routes || this.$options.routes;

        // 递归遍历
        for (const route of routes) {
            if (route.path === '/' && this.current === '/') {
                this.matched.push(route);
                return;
            }

            // /about/info
            if (route.path !== '/' && this.current.indexOf(route.path) !== -1) {
                this.matched.push(route);
                if(route.children) {
                    this.match(route.children);
                }
                return;
            }
        }
    }
}
// 参数1是Vue.use调用时传入的
VueRouter.install = function (_Vue) {
    Vue = _Vue;

    // 1.挂载$router属性
    // this.$router.push()
    // 全局混入目的：延迟下面逻辑到router创建完毕并且附加到选项上时才执行
    Vue.mixin({
        beforeCreate() {
            // 次钩子在每个组件创建实例时都会调用
            // 根实例才有该选项
            if (this.$options.router) {
                Vue.prototype.$router = this.$options.router;
            }
        },
    });

    // 2.注册实现两个组件router-view,router-link

      Vue.component("router-link", {
        props: {
          to: {
            type: String,
            required: true,
          },
        },
        render(h) {
          // <a href="to">xxx</a>
          // return <a href={'#'+this.to}>{this.$slots.default}</a>
          return h(
            "a",
            {
              attrs: {
                href: "#" + this.to,
              },
            },
            this.$slots.default
          );
        },
      });
    

    // Vue.component('router-link', Link);
    Vue.component('router-view', View);
};

export default VueRouter;